#include "catch.hpp"
#include "coherentElastic/coherentElastic_util/fccLatticeFactors.h"
#include <range/v3/all.hpp>
#include "generalTools/testing.h"

TEST_CASE( "taufcc" ){
  GIVEN( "inputs" ){
    std::vector<std::tuple<int,int,int,double>> inputs
      { {0,0,0,2}, {1,0,0,2}, {0,1,0,2}, {0,0,1,2}, {1,1,0,2},
        {1,0,1,2}, {0,1,1,2}, {1,1,1,2}, {1,2,3,4}, {5,3,6,4},
        {8,7,9,.1} };
    std::vector<double> output { 0, 78.956835, 78.956835, 78.956835,
	210.551561, 210.551561, 105.275780, 289.50839, 2105.51561, 
	13896.403, 936.9544  };
    
    for ( size_t i = 0; i < output.size(); ++i ){
      REQUIRE( taufcc( std::get<0>(inputs[i]), std::get<1>(inputs[i]),
                       std::get<2>(inputs[i]), std::get<3>(inputs[i])) ==
               Approx(output[i]).epsilon(1e-6) );
    }
  } // GIVEN
} // TEST CASE




TEST_CASE( "Function to Compute FCC Lattice Factors" ){
  GIVEN( "aluminum is the requested material" ){
    int lat = 4;
    double a = 4.04e-8, maxTauSq = 5.79115688E19, massScatterer = 4.4418589E-23;
    std::vector<double> b (60000, 0.0), bVec1(100), bVec2(100), bVec3(100);
    int imax = fccLatticeFactors( lat, a, maxTauSq, b);
    
    bVec1 = { 5.776055E19, 2.105253E-9, 5.580134E19, 2.141893E-9, 5.398725E19, 
    2.177581E-9, 5.231829E19, 2.212041E-9, 5.079445E19, 2.244977E-9, 4.941575E19, 
    2.276079E-9, 4.818217E19, 2.305031E-9, 4.709372E19, 2.331517E-9, 4.615039E19, 
    2.355224E-9, 4.535219E19, 2.375860E-9, 4.469912E19, 2.393153E-9, 4.419118E19, 
    2.406868E-9, 4.382836E19, 2.416809E-9, 4.361067E19, 2.422834E-9, 4.353810E19, 
    2.424852E-9, 4.361067E19, 2.422834E-9, 4.382836E19, 2.416809E-9, 4.419118E19, 
    2.406868E-9, 4.469912E19, 2.393153E-9, 4.535219E19, 2.375860E-9, 4.615039E19, 
    2.355224E-9, 4.709372E19, 2.331517E-9, 4.818217E19, 2.305031E-9, 4.941575E19, 
    2.276079E-9, 5.079445E19, 2.244977E-9, 5.231829E19, 2.212041E-9, 5.398725E19, 
    2.177581E-9, 5.580134E19, 2.141893E-9, 5.776055E19, 2.105253E-9, 5.776055E19, 
    2.105253E-9, 5.560783E19, 2.145616E-9, 5.360024E19, 2.185428E-9, 5.173778E19, 
    2.224416E-9, 5.002044E19, 2.262279E-9, 4.844823E19, 2.298693E-9, 4.702115E19, 
    2.333315E-9, 4.573920E19, 2.365787E-9, 4.460237E19, 2.395747E-9, 4.361067E19, 
    2.422834E-9, 4.276409E19, 2.446698E-9, 4.206265E19, 2.467014E-9, 4.150633E19, 
    2.483492E-9, 4.109513E19, 2.495886E-9, 4.082907E19, 2.504005E-9, 4.070813E19, 
    2.507722E-9, 4.073231E19, 2.506977E-9, 4.090163E19, 2.501783E-9, 4.121607E19, 
    2.492222E-9, 4.167564E19, 2.478442E-9, 4.228034E19, 2.460655E-9 }; 
    bVec2 = { 4.283666E19, 2.444625E-9, 4.460237E19, 2.395747E-9, 4.651321E19, 
    2.346021E-9, 5.079445E19, 2.244977E-9, 4.844823E19, 2.298693E-9, 4.624714E19, 
    2.352759E-9, 4.419118E19, 2.406868E-9, 4.228034E19, 2.460655E-9, 4.051462E19, 
    2.513704E-9, 3.889404E19, 2.565538E-9, 3.741858E19, 2.615630E-9, 3.608825E19, 
    2.663404E-9, 3.490305E19, 2.708247E-9, 3.386297E19, 2.749524E-9, 3.296802E19, 
    2.786593E-9, 3.221820E19, 2.818833E-9, 3.161350E19, 2.845664E-9, 3.115393E19, 
    2.866577E-9, 3.083949E19, 2.881153E-9, 3.067018E19, 2.889095E-9, 3.064599E19, 
    2.890235E-9, 3.076693E19, 2.884549E-9, 3.103299E19, 2.872157E-9, 3.144419E19, 
    2.853316E-9, 3.200051E19, 2.828405E-9, 3.270195E19, 2.797906E-9, 3.354853E19, 
    2.762379E-9, 3.454023E19, 2.722434E-9, 3.567706E19, 2.678709E-9, 3.695901E19, 
    2.631842E-9, 3.838609E19, 2.582457E-9, 3.995830E19, 2.531142E-9, 4.167564E19, 
    2.478442E-9, 4.353810E19, 2.424852E-9, 4.941575E19, 2.276079E-9, 4.702115E19, 
    2.333315E-9, 4.477168E19, 2.391213E-9, 4.266734E19, 2.449470E-9, 4.070813E19, 
    2.507722E-9, 3.889404E19, 2.565538E-9, 3.722508E19, 2.622420E-9, 3.570125E19, 
    2.677801E-9, 3.432254E19, 2.731054E-9, 3.308896E19, 2.781496E-9, 3.200051E19, 
    2.828405E-9, 3.105718E19, 2.871038E-9, 3.025898E19, 2.908659E-9, 2.960591E19, 
    2.940565E-9, 2.909797E19, 2.966120E-9, 2.873515E19, 2.984786E-9 };
    bVec3 = { 2.039035E19, 3.543298E-9, 1.809250E19, 3.761583E-9, 1.593978E19, 
    4.007548E-9, 1.393219E19, 4.286573E-9, 1.206973E19, 4.605441E-9, 1.035239E19, 
    4.972784E-9, 8.780184E18, 5.399682E-9, 7.353102E18, 5.900444E-9, 6.071147E18, 
    6.493586E-9, 4.934318E18, 7.202884E-9, 3.942617E18, 8.058008E-9, 3.096043E18, 
    9.093195E-9, 2.394596E18, 1.033960E-8, 1.838275E18, 1.180089E-8, 1.427082E18, 
    1.339354E-8, 1.161016E18, 1.484912E-8, 1.040077E18, 1.568871E-8, 1.064265E18, 
    1.550941E-8, 1.233580E18, 1.440577E-8, 1.548021E18, 1.285972E-8, 2.007590E18, 
    1.129230E-8, 2.612286E18, 9.899417E-9, 3.362109E18, 8.725977E-9, 4.257059E18, 
    7.754703E-9, 5.297136E18, 6.951834E-9, 6.482340E18, 6.284259E-9, 7.812671E18, 
    5.724271E-9, 9.288129E18, 5.249958E-9, 1.090871E19, 4.844324E-9, 1.267443E19, 
    4.494236E-9, 1.458526E19, 4.189506E-9, 2.176905E19, 3.429259E-9, 1.942283E19, 
    3.630477E-9, 1.722174E19, 3.855507E-9, 1.516577E19, 4.108542E-9, 1.325493E19, 
    4.394720E-9, 1.148922E19, 4.720355E-9, 9.868637E18, 5.093208E-9, 8.393179E18, 
    5.522767E-9, 7.062848E18, 6.020465E-9, 5.877644E18, 6.599611E-9, 4.837567E18, 
    7.274556E-9, 3.942617E18, 8.058008E-9, 3.192794E18, 8.954359E-9, 2.588098E18, 
    9.945568E-9, 2.128530E18, 1.096681E-8, 1.814088E18, 1.187930E-8, 1.644773E18, 
    1.247576E-8, 1.620585E18, 1.256852E-8, 1.741524E18, 1.212426E-8 };

    checkPartOfVec(b,bVec1,0);
    checkPartOfVec(b,bVec2,300);
    checkPartOfVec(b,bVec3,30000);
    restAreZero(59569,b);

    REQUIRE( imax == 29783 );

  } // GIVEN
  GIVEN( "lead is the requested material" ){
    int lat = 5;
    double a = 4.94e-8, maxTauSq = 5.79115688E19, massScatterer = 3.4373158E-22;
    std::vector<double> b (60000, 0.0), bVec1(100), bVec2(100), bVec3(100);
    int imax = fccLatticeFactors( lat, a, maxTauSq, b);

    bVec1 = { 4.003880E19, 2.528596E-9, 3.863137E19, 2.574245E-9, 3.732101E19, 
    2.619047E-9, 3.610772E19, 2.662686E-9, 3.499148E19, 2.704823E-9, 3.397231E19, 
    2.745095E-9, 3.305021E19, 2.783126E-9, 3.222517E19, 2.818528E-9, 3.149719E19, 
    2.850914E-9, 3.086627E19, 2.879903E-9, 3.033242E19, 2.905136E-9, 2.989564E19, 
    2.926281E-9, 2.955591E19, 2.943051E-9, 2.931325E19, 2.955207E-9, 2.916766E19, 
    2.962574E-9, 2.911913E19, 2.965042E-9, 2.916766E19, 2.962574E-9, 2.931325E19, 
    2.955207E-9, 2.955591E19, 2.943051E-9, 2.989564E19, 2.926281E-9, 3.033242E19, 
    2.905136E-9, 3.086627E19, 2.879903E-9, 3.149719E19, 2.850914E-9, 3.222517E19, 
    2.818528E-9, 3.305021E19, 2.783126E-9, 3.397231E19, 2.745095E-9, 3.499148E19, 
    2.704823E-9, 3.610772E19, 2.662686E-9, 3.732101E19, 2.619047E-9, 3.863137E19, 
    2.574245E-9, 4.003880E19, 2.528596E-9, 3.863137E19, 2.574245E-9, 3.719160E19, 
    2.623600E-9, 3.584888E19, 2.672281E-9, 3.460323E19, 2.719955E-9, 3.345464E19, 
    2.766252E-9, 3.240312E19, 2.810778E-9, 3.144866E19, 2.853113E-9, 3.059126E19, 
    2.892819E-9, 2.983093E19, 2.929453E-9, 2.916766E19, 2.962574E-9, 2.860145E19, 
    2.991754E-9, 2.813231E19, 3.016597E-9, 2.776023E19, 3.036746E-9, 2.748522E19, 
    3.051901E-9, 2.730727E19, 3.061828E-9, 2.722638E19, 3.066373E-9, 2.724256E19, 
    3.065463E-9, 2.735580E19, 3.059111E-9, 2.756611E19, 3.047420E-9 };
    bVec2 = { 2.657929E19, 3.103475E-9, 2.756611E19, 3.047420E-9, 2.864999E19, 
    2.989219E-9, 2.983093E19, 2.929453E-9, 3.110893E19, 2.868649E-9, 3.397231E19, 
    2.745095E-9, 3.240312E19, 2.810778E-9, 3.093098E19, 2.876889E-9, 2.955591E19, 
    2.943051E-9, 2.827791E19, 3.008821E-9, 2.709696E19, 3.073687E-9, 2.601309E19, 
    3.137069E-9, 2.502627E19, 3.198320E-9, 2.413652E19, 3.256737E-9, 2.334383E19, 
    3.311570E-9, 2.264821E19, 3.362041E-9, 2.204965E19, 3.407369E-9, 2.154815E19, 
    3.446791E-9, 2.114372E19, 3.479600E-9, 2.083635E19, 3.505170E-9, 2.062605E19, 
    3.522995E-9, 2.051281E19, 3.532706E-9, 2.049663E19, 3.534099E-9, 2.057752E19, 
    3.527147E-9, 2.075547E19, 3.511994E-9, 2.103048E19, 3.488955E-9, 2.140256E19, 
    3.458495E-9, 2.187170E19, 3.421202E-9, 2.243790E19, 3.377760E-9, 2.310117E19, 
    3.328917E-9, 2.386151E19, 3.275451E-9, 2.471890E19, 3.218143E-9, 2.567336E19, 
    3.157756E-9, 2.672489E19, 3.095010E-9, 2.787348E19, 3.030571E-9, 2.911913E19, 
    2.965042E-9, 3.305021E19, 2.783126E-9, 3.144866E19, 2.853113E-9, 2.994417E19, 
    2.923909E-9, 2.853674E19, 2.995144E-9, 2.722638E19, 3.066373E-9, 2.601309E19, 
    3.137069E-9, 2.489685E19, 3.206622E-9, 2.387768E19, 3.274341E-9, 2.295558E19, 
    3.339457E-9, 2.213054E19, 3.401136E-9, 2.140256E19, 3.458495E-9, 2.077164E19, 
    3.510626E-9, 2.023779E19, 3.556628E-9, 1.980101E19, 3.595641E-9 };
    bVec3 = { 7.376845E18, 5.890941E-9, 8.590142E18, 5.459084E-9, 9.900503E18, 
    5.085005E-9, 1.363746E19, 4.332647E-9, 1.210061E19, 4.599560E-9, 1.066084E19, 
    4.900319E-9, 9.318120E18, 5.241503E-9, 8.072469E18, 5.631405E-9, 6.923881E18, 
    6.080582E-9, 5.872357E18, 6.602581E-9, 4.917897E18, 7.214899E-9, 4.060500E18, 
    7.940177E-9, 3.300168E18, 8.807486E-9, 2.636899E18, 9.853108E-9, 2.070693E18, 
    1.111891E-8, 1.601552E18, 1.264298E-8, 1.229474E18, 1.442980E-8, 9.544603E17, 
    1.637725E-8, 7.765100E17, 1.815710E-8, 6.956236E17, 1.918372E-8, 7.118009E17, 
    1.896447E-8, 8.250419E17, 1.761497E-8, 1.035347E18, 1.572451E-8, 1.342715E18, 
    1.380791E-8, 1.747148E18, 1.210473E-8, 2.248644E18, 1.066988E-8, 2.847203E18, 
    9.482235E-9, 3.542827E18, 8.500510E-9, 4.335514E18, 7.684218E-9, 5.225265E18, 
    6.999480E-9, 6.212080E18, 6.419504E-9, 7.295959E18, 5.923505E-9, 8.476901E18, 
    5.495427E-9, 9.754907E18, 5.122812E-9, 1.455956E19, 4.193202E-9, 1.299037E19, 
    4.439247E-9, 1.151823E19, 4.714407E-9, 1.014316E19, 5.023811E-9, 8.865156E18, 
    5.373742E-9, 7.684214E18, 5.771919E-9, 6.600335E18, 6.227833E-9, 5.613521E18, 
    6.753087E-9, 4.723769E18, 7.361658E-9, 3.931082E18, 8.069821E-9, 3.235459E18, 
    8.895125E-9, 2.636899E18, 9.853108E-9, 2.135403E18, 1.094914E-8, 1.730970E18, 
    1.216116E-8, 1.423602E18, 1.340991E-8, 1.213297E18, 1.452568E-8 };


    checkPartOfVec(b,bVec1,0);
    checkPartOfVec(b,bVec2,300);
    checkPartOfVec(b,bVec3,30000);
    restAreZero(59581,b);

    REQUIRE( imax == 29789 );


 
  } // GIVEN
} // TEST CASE
